/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package entity.establishment;

import entity.tta.OutletDataModel;
import entity.tx.Cuisine;
import entity.tx.FoodItem;
import entity.tx.OutletReservation;
import entity.tx.OutletSeatArea;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;

/**
 *
 * @author Tai Hock
 */
@Entity(name = "OutletFood")
public class OutletFood extends Outlet implements Serializable, Comparable {
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @ManyToMany(targetEntity = Cuisine.class, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, fetch = FetchType.EAGER)
    private List<Cuisine> cuisines = new ArrayList<Cuisine>();
    @ManyToOne(targetEntity = StakeholderFood.class, cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE}, fetch = FetchType.EAGER)
    private StakeholderFood stakeholder; //CM team called it "stakeholderFood", we are using the Tx team's name
    @OneToMany(cascade = {CascadeType.PERSIST})
    private List<OutletSeatArea> seatingAreas = new ArrayList<OutletSeatArea>();
    @OneToMany(cascade = {CascadeType.ALL})
    private List<FoodItem> foodMenu = new ArrayList<FoodItem>();
    @OneToMany(cascade = {CascadeType.ALL}, mappedBy = "outlet")
    private List<OutletReservation> reservations = new ArrayList<OutletReservation>();
    @OneToOne(cascade = {CascadeType.ALL})
    private OutletDataModel outletDataModel;
    private Double noShowPenalty;
    private Boolean autoConfirmReservation;
    private Integer bookingWindow;
    private Integer leadTime_Day;
    private String pathName; //Restaurant layout image URL
    @Column(length = 4096)
    private String managerEmails;
    //Methods used by Tx Team
//-----------------------------------------------------------------------------

    public void addArea(OutletSeatArea area) {
        seatingAreas.add(area);
    }
    
    public void removeArea(OutletSeatArea area) {
        final Long id = area.getId();
        if (seatingAreas.contains(area)) {
            seatingAreas.remove(area);
        }
    }

//-----------------------------------------------------------------------------
    //Outlet Manager Codes by Randall
    //-----------------------------------------------------------------------------------------------------------
    /*
     * An "outlet manager" is simply an Account that is allowed to manage a specific outlet
     * Each outlet stores a list of Account emails corresponding to the managers associated to that outler
     * The email addresses are stored in a string. Each email address is delimited by a whitespace at the front and back
     */
    public String addManager(String email) {
        email = email.toLowerCase();
        if (getManagerEmails() == null) {
            setManagerEmails(" " + email + " ");
            return email + " is successfully ADDED as an outlet manager of outlet: " + this.getOutletName();
        }
        if (getManagerEmails().contains(email)) {
            return email + " is already registered as a manager of this outlet";
        }
        
        setManagerEmails(getManagerEmails() + " " + email + " "); //Append whitespace at the back because all addresses are delimited by whitespace
        return email + " is successfully ADDED as an outlet manager of outlet: " + this.getOutletName();
    }
    
    public String removeManager(String email) {
        email = email.toLowerCase();
        if (!managerEmails.contains(email)) {
            return email + "is not registered as a manager of this outlet";
        }
        
        setManagerEmails(getManagerEmails().replaceAll(" " + email + " ", ""));
        return email + " is successfully REMOVED as an outlet manager of outlet: " + this.getOutletName();
    }
    
    public List<String> retrieveManagerEmailsAsList() {
        List<String> stringList = new ArrayList<String>();
        
        if (getManagerEmails() == null) {
            return stringList;
        }
        
        String[] tempArray = getManagerEmails().split("  "); //Split according to double whitespace because due to the delimiters, email addresses will be separated by 2 whitepaces
        for (int i = 0; i < tempArray.length; i++) {
            stringList.add(tempArray[i].trim());
        }
        
        Collections.sort(stringList); //The list of email addresses will be sorted in alphabetical order
        return stringList;
    }

    //End OutletFood Manager Codes
    //-----------------------------------------------------------------------------------------------------------
    /**
     * @return the cuisines
     */
    public List<Cuisine> getCuisines() {
        return cuisines;
    }

    /**
     * @param cuisines the cuisines to set
     */
    public void setCuisines(List<Cuisine> cuisines) {
        this.cuisines=cuisines;
    }

    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * @return the stakeholder
     */
    public StakeholderFood getStakeholder() {
        return stakeholder;
    }

    /**
     * @param stakeholder the stakeholder to set
     */
    public void setStakeholder(StakeholderFood stakeholder) {
        this.stakeholder = stakeholder;
    }

    /**
     * @return the seatingAreas
     */
    public List<OutletSeatArea> getSeatingAreas() {
        return seatingAreas;
    }

    /**
     * @param seatingAreas the seatingAreas to set
     */
    public void setSeatingAreas(List<OutletSeatArea> seatingAreas) {
        this.seatingAreas = seatingAreas;
    }

    /**
     * @return the foodMenu
     */
    public List<FoodItem> getFoodMenu() {
        return foodMenu;
    }

    /**
     * @param foodMenu the foodMenu to set
     */
    public void setFoodMenu(List<FoodItem> foodMenu) {
        this.foodMenu = foodMenu;
    }

    /**
     * @return the reservations
     */
    public List<OutletReservation> getReservations() {
        return reservations;
    }

    /**
     * @param reservations the reservations to set
     */
    public void setReservations(List<OutletReservation> reservations) {
        this.reservations = reservations;
    }

    /**
     * @return the noShowPenalty
     */
    public Double getNoShowPenalty() {
        return noShowPenalty;
    }

    /**
     * @param noShowPenalty the noShowPenalty to set
     */
    public void setNoShowPenalty(Double noShowPenalty) {
        this.noShowPenalty = noShowPenalty;
    }

    /**
     * @return the autoConfirmReservation
     */
    public Boolean getAutoConfirmReservation() {
        return autoConfirmReservation;
    }

    /**
     * @param autoConfirmReservation the autoConfirmReservation to set
     */
    public void setAutoConfirmReservation(Boolean autoConfirmReservation) {
        this.autoConfirmReservation = autoConfirmReservation;
    }

    /**
     * @return the bookingWindow
     */
    public Integer getBookingWindow() {
        return bookingWindow;
    }

    /**
     * @param bookingWindow the bookingWindow to set
     */
    public void setBookingWindow(Integer bookingWindow) {
        this.bookingWindow = bookingWindow;
    }

    /**
     * @return the leadTime_Day
     */
    public Integer getLeadTime_Day() {
        return leadTime_Day;
    }

    /**
     * @param leadTime_Day the leadTime_Day to set
     */
    public void setLeadTime_Day(Integer leadTime_Day) {
        this.leadTime_Day = leadTime_Day;
    }

    /**
     * @return the pathName
     */
    public String getPathName() {
        return pathName;
    }

    /**
     * @param pathName the pathName to set
     */
    public void setPathName(String pathName) {
        this.pathName = pathName;
    }

    /**
     * @return the outletDataModel
     */
    public OutletDataModel getOutletDataModel() {
        return outletDataModel;
    }

    /**
     * @param outletDataModel the outletDataModel to set
     */
    public void setOutletDataModel(OutletDataModel outletDataModel) {
        this.outletDataModel = outletDataModel;
    }
    
    public void addReservations(OutletReservation r) {
        for (OutletReservation o : this.reservations) {
            if (o.getId().longValue() == r.getId().longValue()) {
                return;
            }
        }
        this.reservations.add(r);
    }
    
    public void removeFoodItem(FoodItem item) {
        this.foodMenu.remove(item);
    }

    public void addFoodItem(FoodItem f) {
        this.foodMenu.add(f);
    }

    /**
     * @return the managerEmails
     */
    public String getManagerEmails() {
        return managerEmails;
    }

    /**
     * @param managerEmails the managerEmails to set
     */
    public void setManagerEmails(String managerEmails) {
        this.managerEmails = managerEmails;
    }
    
    
}
